import { APlugin } from '../types/common.interface';
import { ExecuteRecord } from './execute-record';
import { Injectable, Inject } from '../decorators/inject';
import { CellTypeManage } from './cell-type-manage';
import { NPluginManage } from '../types/cors';
type TPluginConstruct = {new (...agrs: any[]): APlugin};
type TPluginName = string;

@Injectable('PluginManager')
export class PluginManager implements NPluginManage.IPluginManage{
    protected store: APlugin[] = [];
    constructor(
        protected executeRecord: ExecuteRecord,
        protected cellTypeManage: CellTypeManage
    ) {
        this.store.push(executeRecord);
    }
    public load(plugin: TPluginConstruct) {
        let isExist = this.isExist(plugin);
        if(isExist != null) {
            return isExist;
        }
        try {
            let instance = this.factory(plugin);
            // instance.init();
            this.store.push(instance);
        } catch (error) {
            console.dir(plugin)
            console.error(error);
            throw new Error('load plugin faild!')
        }
    }
    public remove(plugin: TPluginName | APlugin | TPluginConstruct) {
        let instance = this.isExist(plugin);
        if(instance == null) {
            return { msg: 'plugin is not exist!', code: 1};
        }
        for(let i = 0; i < this.store.length; i++) {
            if(this.store[i] == instance) {
                instance.destroy();
                this.store.splice(i, 1);
                return null;
            }
        }
        return {msg: 'unkown!', code: -1};
    }
    public getPlugin<T extends APlugin>(identification: TPluginName | APlugin | TPluginConstruct): T {
        return this.isExist(identification) as T;
    }
    protected isExist(identification: TPluginName | APlugin | TPluginConstruct): APlugin {
        if(typeof identification == 'string') {
            for(let item of this.store) {
                if((<any>item.constructor).pluginName == identification) {
                    return item;
                }
            }
        }
        if(identification instanceof Function) {
            for(let item of this.store) {
                if(identification == item.constructor) {
                    return item;
                }
            }
        }
        for(let item of this.store) {
            if(item == identification) {
                return item;
            }
        }
        return null;
    }
    protected factory(plugin: TPluginConstruct): APlugin {
        // 占位，不写具体实现
        return null;
    }
}